local httpclient     = require "shared.http.client"
local contenthelper  = require "shared.http-content-helper"
local config         = require "config"
local cjson          = require("cjson.safe")
      cjson.encode_max_depth(32)
      cjson.decode_max_depth(32)
local def            = require("shared.api.def")
local ERROR_CODE     = def.ERROR_CODE

local DATA_GATEWAY = config.ENV.DATAGATE_SERVICE


local _M = { _VERSION = "0.1" }

local function _fill_response_header(headers)
  if type(headers) == 'table' then
    for k, v in pairs(headers) do
      if string.lower(k) == 'content-type' then
        ngx.header[k] = v
      end
    end
  end
end

local function _resolve_response(resp)
  if resp.status ~= 200 then
    if resp.status == 400 then
      if contenthelper.match_content_type(resp, 'application/json')  then
        local content = contenthelper.decode(resp.headers, resp.body)
        local err     = cjson.decode(content)
        return nil, err
      end
    end

    ngx.status = resp.status
    _fill_response_header(resp.headers)
    ngx.say(resp.body)
    ngx.exit(ngx.OK)
  end

  local content = contenthelper.decode(resp.headers, resp.body)
  return cjson.decode(content)
end


-- account
do
  local ACCOUNT = {}
  local ACCOUNT_PATH                       = "/account"
  local ACCOUNT_LEVEL_PATH                 = ACCOUNT_PATH.."/level"
  local ACCOUNT_VIP_BONUS_PATH             = ACCOUNT_PATH.."/vip_bonus"
  local ACCOUNT_VIP_BONUS_SUMMARY_PATH     = ACCOUNT_PATH.."/vip_bonus/summary"
  local ACCOUNT_WALLET_ADDRESS_PATH        = ACCOUNT_PATH.."/wallet_address"
  local ACCOUNT_WALLET_ADDRESS_POLICY_PATH = ACCOUNT_PATH.."/wallet_address/policy"

  function ACCOUNT.peek(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACCOUNT_PATH)
      :body(data)
      :send("PEEK", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end


  function ACCOUNT.view_level(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACCOUNT_LEVEL_PATH)
      :body(data)
      :send("VIEW", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end


  function ACCOUNT.view_vip_bonus(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACCOUNT_VIP_BONUS_PATH)
      :body(data)
      :send("VIEW", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end


  function ACCOUNT.redeem_vip_bonus(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACCOUNT_VIP_BONUS_PATH)
      :body(data)
      :send("REDEEM", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end


  function ACCOUNT.view_vip_bonus_summary(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACCOUNT_VIP_BONUS_SUMMARY_PATH)
      :body(data)
      :send("VIEW", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end


  function ACCOUNT.view_wallet_address(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACCOUNT_WALLET_ADDRESS_PATH)
      :body(data)
      :send("VIEW", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end


  function ACCOUNT.put_wallet_address(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACCOUNT_WALLET_ADDRESS_PATH)
      :body(data)
      :send("PUT", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end


  function ACCOUNT.view_wallet_address_policy(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACCOUNT_WALLET_ADDRESS_POLICY_PATH)
      :body(data)
      :send("VIEW", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  -- export
  _M.account = ACCOUNT
end


-- level
do
  local LEVEL = {}
  local LEVEL_PATH = "/level"

  function LEVEL.view(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..LEVEL_PATH)
      :body(data)
      :send("VIEW", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  -- export
  _M.level = LEVEL
end


-- withdrawal_slip
do
  local WITHDRAWAL_SLIP = {}
  local WITHDRAWAL_SLIP_PATH = "/withdrawal_slip"

  function WITHDRAWAL_SLIP.create(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..WITHDRAWAL_SLIP_PATH)
      :body(data)
      :send("CREATE", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  function WITHDRAWAL_SLIP.cancel(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..WITHDRAWAL_SLIP_PATH)
      :body(data)
      :send("CANCEL", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  -- export
  _M.withdrawal_slip = WITHDRAWAL_SLIP
end

-- activity_register_reward
do
  local ACTIVITY_REGISTER_REWARD = {}
  local ACTIVITY_REGISTER_REWARD_PATH = "/activity_register_reward"

  function ACTIVITY_REGISTER_REWARD.peek(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACTIVITY_REGISTER_REWARD_PATH)
      :body(data)
      :send("PEEK", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  function ACTIVITY_REGISTER_REWARD.met(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACTIVITY_REGISTER_REWARD_PATH)
      :body(data)
      :send("MET", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.exit(ngx.OK)
      ngx.say(err)
    end

    return _resolve_response(resp)
  end

  function ACTIVITY_REGISTER_REWARD.round_total(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACTIVITY_REGISTER_REWARD_PATH.."/round")
      :body(data)
      :send("TOTAL", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  -- export
  _M.activity_register_reward = ACTIVITY_REGISTER_REWARD
end



-- 活动奖励提现条件
do
  local ACTIVITY_REWARD_WITHDRAW_CONDITIONS = {}
  local ACTIVITY_REWARD_WITHDRAW_CONDITIONS_PATH = "/activity_reward_withdraw_conditions"

  function ACTIVITY_REWARD_WITHDRAW_CONDITIONS.peek(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACTIVITY_REWARD_WITHDRAW_CONDITIONS_PATH)
      :body(data)
      :send("PEEK", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  function ACTIVITY_REWARD_WITHDRAW_CONDITIONS.met(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACTIVITY_REWARD_WITHDRAW_CONDITIONS_PATH)
      :body(data)
      :send("MET", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  function ACTIVITY_REWARD_WITHDRAW_CONDITIONS.round_total(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ACTIVITY_REWARD_WITHDRAW_CONDITIONS_PATH.."/round")
      :body(data)
      :send("TOTAL", 2000, nil)

    if err or (not resp) then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.OK)
    end

    return _resolve_response(resp)
  end

  -- export
  _M.activity_reward_withdraw_conditions = ACTIVITY_REWARD_WITHDRAW_CONDITIONS
end


-- adjust
do
  local ADJUST_DEVICE = {}
  local ADJUST_DEVICE_PATH = "/adjust_device"

  function ADJUST_DEVICE.create(args)
    local data = cjson.encode(args)
    local resp, err = httpclient.new()
      :uri(DATA_GATEWAY..ADJUST_DEVICE_PATH)
      :body(data)
      :send("CREATE", 2000, nil)

    if err or (not resp) then
      return nil, err
    end

    if resp.status ~= 200 then
      if resp.status == 400 then
        if contenthelper.match_content_type(resp, 'application/json')  then
          local content = contenthelper.decode(resp.headers, resp.body)
          local err     = cjson.decode(content)
          return nil, err
        end
      end

      return nil, resp.status
    end

    local content = contenthelper.decode(resp.headers, resp.body)
    return cjson.decode(content), nil
  end

  -- export
  _M.adjust_device = ADJUST_DEVICE
end



return _M
